/*
permutationIterator:  Fancy iterator, this iterator takes two collections
                      one for an elements and the other for an indexes,
                      the element returned from a dereference stay in
                      the indexed position from index collection
    Copyright (C) 2012  Jorge E. A. Atala
                        FuDePAN
    This file is part of the Fui Proyect.

    Fui is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Fui is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Fui.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PERMUTATION_ITERATOR_H
#   define PERMUTATION_ITERATOR_H
#   include "iteratorBase.h"
namespace fui
{
template<class ElementIterator, class IndexIterator>
class PermutationIterator : public IteratorBase<typename ElementIterator::value_type>
{
private:
    ElementIterator it;
    IndexIterator index;
    typedef typename ElementIterator::value_type Element;
public:
    PermutationIterator(const ElementIterator& it, const IndexIterator& index);

    inline Element operator*() const;

    inline PermutationIterator<ElementIterator, IndexIterator> operator+(const size_t ind) const;

    inline PermutationIterator<ElementIterator, IndexIterator> operator-(const size_t ind) const;

    inline PermutationIterator<ElementIterator, IndexIterator> operator-(const PermutationIterator<ElementIterator, IndexIterator> other) const;

    inline PermutationIterator<ElementIterator, IndexIterator>& operator++();

    inline PermutationIterator<ElementIterator, IndexIterator>& operator--();

    inline PermutationIterator<ElementIterator, IndexIterator> operator++(const int);

    inline PermutationIterator<ElementIterator, IndexIterator> operator--(const int);

    inline bool operator==(const PermutationIterator<ElementIterator, IndexIterator>& other)const;

    inline bool operator!=(const PermutationIterator<ElementIterator, IndexIterator>& other)const;

    inline bool operator<(const PermutationIterator<ElementIterator, IndexIterator>& other)const;
};
}
#define PERMUTATION_ITERATOR_IMP
#   include "permutationIterator_imp.h"
#undef PERMUTATION_ITERATOR_IMP

#endif
